﻿using DIT.Business.Contract;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using DIT.Domain;
using DIT.Contract;
using System.Collections.Generic;
using System.Linq;
using DIT.DB.Database;
using DIT.DB.DAL;
using DIT.Utility;
using DIT.Service;

namespace DIT.Business.Contract.UnitTest
{
    
    
    /// <summary>
    ///This is a test class for ITaxPayerServiceTest and is intended
    ///to contain all ITaxPayerServiceTest Unit Tests
    ///</summary>
    [TestClass()]
    public class ITaxPayerServiceTest
    {
        private DatabaseBase database;
        private IRepository repository;
        private ITaxPayerService taxpayerService;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}

        //Use TestInitialize to run code before running each test
        [TestInitialize()]
        public void MyTestInitialize()
        {
            database = DatabaseFactory.GetDatabase(DITConfig.AppSettings["DatabaseType"]);
            repository = new DITRepository(database);
        }
        
        //Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup()
        {
            database = null;
            repository = null;
            taxpayerService = null;
        }

        #endregion


        private ITaxPayerService CreateITaxPayerService()
        {
            // TODO: Instantiate an appropriate concrete class.
            if (taxpayerService == null)
                taxpayerService = new TaxPayerService(repository);
            return taxpayerService;
        }
        private Account SampleClient(TaxPayerTypeENUM taxPayerType, bool isDefault)
        {
            switch (taxPayerType)
            {
                case TaxPayerTypeENUM.Firm:
                    return isDefault ? FirmAccount.Default : FirmAccount.Sample;
                case TaxPayerTypeENUM.HUF:
                    return isDefault ? HUFAccount.Default : HUFAccount.Sample;
                case TaxPayerTypeENUM.Individual:
                    return isDefault ? IndividualAccount.Default : IndividualAccount.Sample;
                default:
                    return null;
            }
        }

        /// <summary>
        ///A test for GetAllEmployerCategory
        ///</summary>
        //[TestMethod()]
        //public void GetAllEmployerCategoryTest()
        //{
        //    ITaxPayerService target = CreateITaxPayerService();
        //    IEnumerable<KeyValuePair<EmployerCategoryENUM, string>> expected = null; // TODO: Initialize to an appropriate value
        //    IEnumerable<KeyValuePair<EmployerCategoryENUM, string>> actual;
        //    actual = target.GetAllEmployerCategory();
        //    Assert.AreEqual(expected, actual);
        //    Assert.Inconclusive("Verify the correctness of this test method.");
        //}

        /// <summary>
        ///A test for GetAllGender
        ///</summary>
        //[TestMethod()]
        //public void GetAllGenderTest()
        //{
        //    ITaxPayerService target = CreateITaxPayerService();
        //    IEnumerable<KeyValuePair<GenderENUM, string>> expected = null; // TODO: Initialize to an appropriate value
        //    IEnumerable<KeyValuePair<GenderENUM, string>> actual;
        //    actual = target.GetAllGender();
        //    Assert.AreEqual(expected, actual);
        //    Assert.Inconclusive("Verify the correctness of this test method.");
        //}

        /// <summary>
        ///A test for GetAllState
        ///</summary>
        //[TestMethod()]
        //public void GetAllStateTest()
        //{
        //    ITaxPayerService target = CreateITaxPayerService();
        //    IEnumerable<KeyValuePair<StateCodeENUM, string>> expected = null; // TODO: Initialize to an appropriate value
        //    IEnumerable<KeyValuePair<StateCodeENUM, string>> actual;
        //    actual = target.GetAllState();
        //    Assert.AreEqual(expected, actual);
        //    Assert.Inconclusive("Verify the correctness of this test method.");
        //}

        /// <summary>
        ///A test for CreateTaxPayer
        ///</summary>
        [TestMethod()]
        public void CreateTaxPayerTest()
        {
            ITaxPayerService target = CreateITaxPayerService();
            Account actual = target.GetClientById(target.CreateTaxPayer(SampleClient(TaxPayerTypeENUM.Individual, false)));

            Assert.IsNotNull(actual, "Account not created");
        }

        /// <summary>
        ///A test for DeleteTaxPayer
        ///</summary>
        [TestMethod()]
        public void DeleteTaxPayerTest()
        {
            ITaxPayerService target = CreateITaxPayerService();
            Guid taxPayerId;
            IEnumerable<Account> allClient = target.GetAllClient();
            if (allClient == null || allClient.Count() == 0)
                taxPayerId = target.CreateTaxPayer(SampleClient(TaxPayerTypeENUM.HUF, false));
            else
                taxPayerId = allClient.First().ID;
            target.DeleteTaxPayer(taxPayerId);
            Account deletedClient = target.GetClientById(taxPayerId);
            Assert.IsNull(deletedClient, "Account still exist after deletion.");
        }

        /// <summary>
        ///A test for GetAllClient
        ///</summary>
        [TestMethod()]
        public void GetAllClientTest()
        {
            ITaxPayerService target = CreateITaxPayerService();

            int previousCount = 0;
            IEnumerable<Account> allClient = target.GetAllClient();
            if (allClient != null && allClient.Count() > 0)
                previousCount = allClient.Count();

            target.CreateTaxPayer(SampleClient(TaxPayerTypeENUM.HUF, false));
            target.CreateTaxPayer(SampleClient(TaxPayerTypeENUM.HUF, false));
            target.CreateTaxPayer(SampleClient(TaxPayerTypeENUM.HUF, false));

            allClient = target.GetAllClient();
            Assert.IsNotNull(allClient, "Not returning any value");
            Assert.IsTrue(allClient.Count() == previousCount + 3, "Not returning all values");
        }

        /// <summary>
        ///A test for GetById
        ///</summary>
        [TestMethod()]
        public void GetClientByIdTest()
        {
            CreateTaxPayerTest();
        }

        /// <summary>
        ///A test for GetClientByLastName
        ///</summary>
        [TestMethod()]
        public void GetClientByLastNameTest()
        {
            ITaxPayerService target = CreateITaxPayerService();
            Account c = SampleClient(TaxPayerTypeENUM.Individual, false);
            c.AccountInfo.AssesseeName = new AssesseeName("lastName", c.AccountInfo.AssesseeName.FirstName, c.AccountInfo.AssesseeName.MiddleName, c.AccountInfo.AssesseeName.OrgOldName);
            target.CreateTaxPayer(c);

            IEnumerable<Account> cList = target.GetClientByLastName("lastname");

            Assert.IsNotNull(cList, "Get by last name not working");
            Account nc = cList.FirstOrDefault(ct => { return !ct.AccountInfo.AssesseeName.SurNameOrOrgName.Equals("lastname", StringComparison.CurrentCultureIgnoreCase); });
            Assert.IsNull(nc, "Get by last name not working");
        }

        /// <summary>
        ///A test for GetClientByMobile
        ///</summary>
        [TestMethod()]
        public void GetClientByMobileTest()
        {
            ITaxPayerService target = CreateITaxPayerService();
            Account c = SampleClient(TaxPayerTypeENUM.HUF, false);
            ulong mobile = 9874715171;
            c.AccountInfo.MobileNo = mobile;
            target.CreateTaxPayer(c);

            IEnumerable<Account> cList = target.GetClientByMobile(mobile);

            Assert.IsNotNull(cList, "Get by mobile not working");
            Account nc = cList.FirstOrDefault(ct => { return ct.AccountInfo.MobileNo != mobile; });
            Assert.IsNull(nc, "Get by mobile not working");
        }

        /// <summary>
        ///A test for GetClientByPAN
        ///</summary>
        [TestMethod()]
        public void GetClientByPANTest()
        {
            ITaxPayerService target = CreateITaxPayerService();
            Account c = SampleClient(TaxPayerTypeENUM.Individual, false);
            string pan = "APGPG6370q";
            c.PAN = pan;
            target.CreateTaxPayer(c);

            c = target.GetClientByPAN(pan);

            Assert.IsNotNull(c, "Get by PAN not working");
        }

        /// <summary>
        ///A test for ModifyTaxPayer
        ///</summary>
        [TestMethod()]
        public void ModifyTaxPayerTest()
        {
            ITaxPayerService target = CreateITaxPayerService();
            Account client;
            IEnumerable<Account> allClient = target.GetAllClient();
            if (allClient == null || allClient.Count() == 0)
                client = target.GetClientById(target.CreateTaxPayer(SampleClient(TaxPayerTypeENUM.HUF, false)));
            else
                client = allClient.First();

            string exactFirstName = "Paramita";
            client.AccountInfo.AssesseeName = new AssesseeName(client.AccountInfo.AssesseeName.SurNameOrOrgName, exactFirstName, client.AccountInfo.AssesseeName.MiddleName, client.AccountInfo.AssesseeName.OrgOldName);
            target.ModifyTaxPayer(client);
            string actualFirstName = client.AccountInfo.AssesseeName.FirstName;

            Assert.IsTrue(exactFirstName == actualFirstName, "Modification not happening");
        }

        /// <summary>
        ///A test for CreateFilingStatus
        ///</summary>
        [TestMethod()]
        public void CreateFilingStatusTest()
        {
            ITaxPayerService target = CreateITaxPayerService();
            Account client = target.GetClientById(target.CreateTaxPayer(SampleClient(TaxPayerTypeENUM.Individual, false)));
            Assert.IsNotNull(client, "Client not created");

            FilingStatus filingStatus = target.GetFilingStatusById(target.CreateFilingStatus(FilingStatus.DefaultFilingStatus(client, "2012-2013")));
            Assert.IsNotNull(filingStatus, "FilingStatus not created");
        }

        /// <summary>
        ///A test for GetFilingStatusById
        ///</summary>
        [TestMethod()]
        public void GetFilingStatusByIdTest()
        {
            CreateFilingStatusTest();
        }

        /// <summary>
        ///A test for GetFilingStatus
        ///</summary>
        [TestMethod()]
        public void GetFilingStatusTest()
        {
            ITaxPayerService target = CreateITaxPayerService();
            Account client = target.GetClientById(target.CreateTaxPayer(SampleClient(TaxPayerTypeENUM.Individual, false)));
            Assert.IsNotNull(client, "Client not created");

            target.CreateFilingStatus(FilingStatus.DefaultFilingStatus(client, "2012-2013"));
            target.CreateFilingStatus(FilingStatus.DefaultFilingStatus(client, "2011-2012"));

            FilingStatus fs = target.GetFilingStatus(client, "2011-2012");
            Assert.IsNotNull(fs, "Not returning any value");
        }

        /// <summary>
        ///A test for GetFilingStatus
        ///</summary>
        [TestMethod()]
        public void GetFilingStatusByClientTest()
        {
            ITaxPayerService target = CreateITaxPayerService();
            Account client = target.GetClientById(target.CreateTaxPayer(SampleClient(TaxPayerTypeENUM.Individual, false)));
            Assert.IsNotNull(client, "Client not created");

            target.CreateFilingStatus(FilingStatus.DefaultFilingStatus(client, "2012-2013"));
            target.CreateFilingStatus(FilingStatus.DefaultFilingStatus(client, "2011-2012"));
            target.CreateFilingStatus(FilingStatus.DefaultFilingStatus(client, "2010-2011"));
            target.CreateFilingStatus(FilingStatus.DefaultFilingStatus(client, "2009-2010"));

            IEnumerable<FilingStatus> fsList = target.GetFilingStatusByClient(client);
            Assert.IsNotNull(fsList, "Not returning any value");
            Assert.IsTrue(fsList.Count() == 4, "Not returning all values");
        }

        /// <summary>
        ///A test for ModifyFilingStatus
        ///</summary>
        [TestMethod()]
        public void ModifyFilingStatusTest()
        {
            ITaxPayerService target = CreateITaxPayerService();
            Account client = target.GetClientById(target.CreateTaxPayer(SampleClient(TaxPayerTypeENUM.Individual, false)));
            Assert.IsNotNull(client, "Client not created");

            FilingStatus filingStatus = target.GetFilingStatusById(target.CreateFilingStatus(FilingStatus.DefaultFilingStatus(client, "2012-2013")));

            string exactAsseseeRepAddress = "Siliguri";
            filingStatus.AsseseeRepAddress = exactAsseseeRepAddress;
            target.ModifyFilingStatus(filingStatus);
            string actualAsseseeRepAddress = filingStatus.AsseseeRepAddress;

            Assert.IsTrue(exactAsseseeRepAddress == actualAsseseeRepAddress, "Modification not happening");
        }
    }
}